CliClass.php

<?php

namespace Taeluf\Tester;

class Cli {

    protected $testDir;
    protected $config;
    protected $autoload;
    protected $directAutoload;
    protected $testDirs = [];
    protected $pwd;

    public function __construct($workingDir){
        $this->pwd = $workingDir;
        $dir = $workingDir;
        $bn = basename($dir);
        $testDir = null;
        if ($bn=='test'||$bn=='tests'){
            $testDir = $dir;
            //we're IN the test directory
        } else if (is_dir($target=$dir.'/test/') || is_dir($target=$dir.'/tests/')){
            $testDir = $target;
        }
        if ($testDir==null){
          echo "We couldn't find your test directory. Expecting 'test' or 'tests'. This should be run from the test directory or its parent directory.";
        }
        $this->testDir = $testDir;
        $config = $testDir.'/tlf-test.json';
        $this->config = file_exists($config) ? json_decode(file_get_contents($config), true) : [];
    }

    public function autoload(){
      //autoload files from the root/src dir or root/code or just root/
      // I'm gonna have to scan for class names
      // So that minimal configuration is required. That's kinda the point.
      // So I'll probably want to output a classmap file
      // which... might mean integrating with my autoloader lib which isn't a full lib yet.
      // or I can set a system-wide autoloader... I like that idea too
      // var_dump($this->autoload);
        require_once($this->autoload);
    }

    public function loadConfig(){
        $path = dirname(__DIR__).'/user-settings/system.json';
        $configs = [];
        if (!file_exists($path)){
            $didFinish = $this->buildConfigFromInput();
            if (!$didFinish)return false;
            $configs['autoload'] = $this->autoload;
            file_put_contents($path, json_encode($configs));
        }

        $configs = json_decode(file_get_contents($path),true);
        $this->autoload = $configs['autoload'];

        return true;
    }
    public function loadProjectConfig(){
        $this->testDirs = $this->config['testDirs'] ?? ['.'];
        $this->directAutoload = $this->config['autoload'] ?? [];
    }

    public function buildConfigFromInput(){
        echo "Enter absolute path to a global autoload file: ";
        $line = trim(fgets(STDIN));
        if (!is_file($line)){
            echo "File path invalid";
            return false;
        }
        $this->autoload = $line;
        return true;
    }

    public function runTests(){
        $this->autoload();
        $parent = $this->testDir;
        $testDirs = $this->testDirs;
        if (($key=array_search('.',$testDirs))!==false){
            $testDirs[$key] = '';
        }
        // print_r($testDirs);
        $testDirs = array_map(
          function($relDir) use ($parent){
              $dir = str_replace(['///','//'],'/',$parent.'/'.$relDir);
              if (substr($dir,-1)=='/')$dir = substr($dir,0,-1);
              return $dir;
          }, $testDirs);
        foreach ($this->directAutoload as $relPath){
            require_once($this->testDir.'/'.$relPath);
        }
        chdir($parent);
        $testSet = \Taeluf\Tester\Utility::runDirectory($testDirs, $this->testDir);

        //maybe do something here with the array???
        return $testSet;
    }

    public function cliOutput($testSet){
        ob_start();
        echo "\n";
        $testCount = [];
        foreach ($testSet as $dir=>$classes){
            echo "Tests in '$dir'\n";
            foreach($classes as $class=>$info){
                foreach ($info['tests'] as $testName => $result){
                    echo "  ";
                    $r = $result;
                    if ($r['disabled'])echo "//";
                    else if ($r['result'])echo "+";
                    else echo "-";
                    echo " $testName";
                    echo "\n";
                }
            }
        }

        echo "\n";

        return ob_get_clean();
    }

    public function htmlOutput($testSet){
        ob_start();
        $testCount = [];
        $testDir = realpath($this->pwd);
        foreach ($testSet as $dir=>$classes){
            $dir = realpath($dir);
            $relDir = $dir;
            $prefix = substr($dir,0,strlen($testDir));
            if ($prefix===$testDir)$relDir = substr($dir,strlen($testDir)+1);

            $pad = "    ";
            echo "<h1>Dir: $relDir</h1>\n";
            echo "$pad<section>";
            // echo "Tests in '$dir'\n";
            foreach($classes as $class=>$info){
                echo "$pad$pad<h2>$class</h2>";
                foreach ($info['tests'] as $testName => $result){
                    echo $result['html'];
                    // echo "  ";
                    // $r = $result;
                    // if ($r['disabled'])echo "//";
                    // else if ($r['result'])echo "+";
                    // else echo "-";
                    // echo " $testName";
                    // echo "\n";
                }
            }
            echo "$pad</section>";
        }

        $htmlOut = ob_get_clean();

        return $htmlOut;
    }

    public function writeTestResults($html){
        $outFile = $this->testDir.'/TestResults.html';
        file_put_contents($outFile, $html);
        $outFile = realpath($outFile);
        echo "\nSee file://$outFile for extended output";

        echo "\n\n";
    }
}